#!/usr/bin/env python3
# -*- coding: us-ascii -*-
# --------------------------------------------------------------------------------
# Copyright (C) 2015-2016 BigDFT group
# This file is distributed under the terms of the
# GNU General Public License, see
# or http://www.gnu.org/copyleft/gpl.txt .
# --------------------------------------------------------------------------------
from __future__ import print_function
from copy import deepcopy
BIGDFT_CFG = 'BIGDFT_CONFIGURE_FLAGS'
CLEAN = ' clean '
CLEANONE = ' cleanone '
UNINSTALL = ' uninstall '
LIST = ' list '
BUILD = ' build '
BUILDONE = ' buildone '
TINDERBOX = ' tinderbox -o buildlogs '
DOT = ' dot '
DOTCMD = ' | dot -Edir=back -Tpng > buildprocedure.png '
DIST = ' dist --dist-only ' # bigdft-suite '
RCFILE = 'buildrc'
MKFILE = 'Makefile'
SETUP = ' setup '
def get_macros(fr, *expressions):
"""
Given a file, find the macros in it.
Args:
fr (str): path of the file to search in.
*expressions: list of expressions to match.
Returns:
(list): a list of macros (strings).
"""
from re import compile, search
regex = [compile(x.strip()) for x in expressions]
result = []
with open(fr) as ifile:
for line in ifile:
if all(search(r, line) for r in regex) \
and "dnl" not in line and '#' not in line:
result.append(line.rstrip('\n'))
return result
def get_files(fd, *expressions):
"""
Given a directory, find the files which match the given macros.
Args:
fd (str): path to the directory to look in.
*expressions: a list of expressions to match.
Returns:
(list): a list of files which have lines that match the expressions.
"""
from os.path import join
from re import compile, search
from glob import glob
regex = [compile(x.strip()) for x in expressions]
result = []
for f in glob(join(fd, "*")):
with open(f) as ifile:
for line in ifile:
if all(search(r, line) for r in regex) \
and "dnl" not in line and '#' not in line:
result.append(f)
break
return result
CHECKMODULES = ['futile', 'atlab', 'chess', 'liborbs',
'psolver', 'bigdft', 'PyBigDFT', 'spred',
'bigdft-client']
MAKEMODULES = deepcopy(CHECKMODULES)
MAKEMODULES.insert(CHECKMODULES.index('bigdft'), 'libABINIT')
MANUALMAKEMODULES = deepcopy(MAKEMODULES)
MANUALMAKEMODULES.remove('PyBigDFT')
# allowed actions and corresponding description
ACTIONS = {'build':
'Compile and install the code with the given configuration.',
'make':
'Recompile the bigdft internal branches, skip configuring step.',
'clean':
'Clean the branches for a fresh reinstall.',
'startover':
'Wipe out all the build directories and recompile the important parts',
'autogen':
'Perform the autogen in the modules which need that. For developers only.',
'update':
'Useful to update a pre-compiled branch after a merge',
'dist':
'Creates a tarfile for the suite tailored to reproduce the compilation options specified.',
'check':
'Perform check in the bigdft branches, skip external libraries.',
'cleanone':
'Clean a single module of the suite',
'buildone':
'Build a single module of the suite',
'dry_run':
"Visualize the list of modules that will be compiled with the provided configuration in the 'buildprocedure.png' file.",
'link':
'Show the linking line that have to be used to connect an external executable to the package (when applicable)'}
# actions which need rcfile to be executed
NEEDRC = ['build', 'dist', 'dry_run', 'startover', 'buildone']
# actions which do not need Makefile creation
NOMAKEFILE = ['autogen', 'dry_run']
TARGETS = {
'bigdft': ['bin', 'bigdft'],
'spred': ['bin', 'mhgps'],
'chess': ['lib', 'libCheSS-1.a'],
'futile': ['lib', 'libfutile-1.a'],
'PyBigDFT': ['bin', 'bigdft'], # not really a target
'bigdft-client': ['lib'], # not really a target
'psolver': ['lib', 'libPSolver-1.a'],
'atlab': ['lib', 'libatlab-1.a'],
'liborbs': ['lib', 'liborbs.a'],
}
[docs]class BigDFTInstaller():
"""Class for the installation of the ``bigdft-suite``.
Attributes:
action (str): Action to be performed.
package (str): Package to install.
rcfile (str): Configuration file.
conditions (list(str)): List of conditions.
verbose (bool): If ``True``, more verbose.
quiet (bool): If ``True``, no messages.
yes (bool): If ``True``, ask a question.
"""
m4_re = ['^AX_', 'CHECK_PYTHON[^_]',
'PKG_CHECK_MODULES'] # regular expressions to identify proprietary macros
def __init__(self, action, package, rcfile, conditions, verbose, quiet, yes):
import os
from sys import executable as pythonpath
self.action = action # Action to be performed
self.conditions = [] if conditions is None else conditions
self.package = package # Package
self.yes = yes # Ask a question
# the position of the script
self.scriptpath = __file__
# look where we are
self.srcdir = os.path.abspath(os.path.dirname(self.scriptpath))
if self.srcdir == '':
self.srcdir = '.'
# look the builddir
self.builddir = os.getcwd()
# look if we are building from a branch
bigdftdir = os.path.join(self.srcdir, 'bigdft')
self.branch = os.path.isfile(os.path.join(bigdftdir, 'branchfile'))
self.verbose = (verbose or action == 'check') # verbose option
if not self.verbose and not quiet:
self.verbose = self.branch
# To be done BEFORE any exit instruction in __init__ (get_rcfile)
self.time0 = None
if os.path.abspath(self.srcdir) == os.path.abspath(self.builddir) and self.action not in NOMAKEFILE:
print(50 * '-')
print("ERROR: BigDFT Installer works better with a build directory different from the source directory, install from another directory")
print("SOLUTION: Create a separate directory and invoke this script from it")
exit(1)
# hostname
self.hostname = os.uname()[1]
# rcfile
self.get_rcfile(rcfile)
# jhbuild script
self.jhb = pythonpath + ' ' + \
os.path.join(self.srcdir, 'bundler/jhbuild.py ')
if self.rcfile != '':
self.jhb += '-f ' + self.rcfile
# conditions to be added
if len(self.conditions) > 0:
self.jhb += ' --conditions=+' + self.conditions[0]
for cond in self.conditions[1:]:
self.jhb += ',+' + cond
# date of bigdft executable if present
self.time0 = self.target_time()
self.print_present_configuration()
# now get the list of modules that has to be treated with the given command
self.modulelist = self.get_output(
self.jhb + LIST + self.package).split('\n')
print(" List of modules to be treated:", self.modulelist)
# then choose the actions to be taken
getattr(self, action)()
def target_time(self):
import os
dt = TARGETS['bigdft']
dt = TARGETS.get(self.package)
# print(TARGETS)
tgt = os.path.join(*dt)
return self.filename_time(os.path.join(self.builddir, 'install', tgt))
def filename_time(self, filename):
import os
if os.path.isfile(filename):
return os.path.getmtime(filename)
else:
return 0
def hook_environment_modifications(self):
"""
Intercepts the `py:func:addpath` method of jhbuild
in order to understand which environment variables have been
identified to compile the suite.
"""
pass
def get_rcfile(self, rcfile):
"""Determine the rcfile"""
import os
# see if the environment variables BIGDFT_CFG is present
self.rcfile = ''
if rcfile is not None:
self.rcfile = rcfile
else:
if not (BIGDFT_CFG in list(os.environ.keys())) or self.action in NEEDRC:
self.rcfile = RCFILE
# see if it exists where specified
if os.path.exists(self.rcfile):
return
# otherwise search again in the rcfiles
rcdir = os.path.join(self.srcdir, 'rcfiles')
if self.rcfile != '':
self.rcfile = os.path.join(rcdir, self.rcfile)
if os.path.exists(self.rcfile):
return
self.rcfile = ''
if BIGDFT_CFG in list(os.environ.keys()):
return
# otherwise search for rcfiles similar to hostname and propose a choice
rcs = []
for file in os.listdir(rcdir):
testname = os.path.basename(file)
base = os.path.splitext(testname)[0]
if base in self.hostname or self.hostname in base or base.split('-')[0] in self.hostname:
rcs.append(file)
print("Search in the configuration directory '%s'" % rcdir)
if len(rcs) == 1:
self.rcfile = os.path.join(rcdir, rcs[0])
elif len(rcs) > 0 and (self.action in NEEDRC or not self.yes):
print("No valid configuration file specified, found various that matches the hostname '%s'" % self.hostname)
print('In the directory "' + rcdir + '"')
print('Choose among the following options')
for i, rc in enumerate(rcs):
print(str(i + 1) + '. ' + rc)
while True:
choice = input('Pick your choice (q to quit) ')
if choice == 'q':
exit(0)
try:
ival = int(choice)
if (ival <= 0):
raise
ch = rcs[ival - 1]
break
except:
print('The choice must be a valid integer among the above')
self.rcfile = os.path.join(rcdir, ch)
elif self.action in NEEDRC:
print('No valid configuration file provided and ' +
BIGDFT_CFG + ' variable not present, exiting...')
exit(1)
def __dump(self, *msg, **kwargs):
if self.verbose and kwargs.get('verbose', True):
for m in msg:
print(m)
def print_present_configuration(self):
import os
indent = ' ' * 2
print('Configuration chosen for the Installer:')
print(indent + 'Hostname:', self.hostname)
print(indent + 'Source directory:', os.path.abspath(self.srcdir))
print(indent + 'Compiling from a branch:', self.branch)
print(indent + 'Build directory:', os.path.abspath(self.builddir))
print(indent + 'Action chosen:', self.action)
print(indent + 'Verbose:', self.verbose)
print(indent + 'Jhbuild baseline:', self.jhb)
if self.rcfile == '' and self.action in NEEDRC:
print(indent + 'Configuration options:')
print(indent * 2 + "Source: Environment variable '%s'" % BIGDFT_CFG)
print(indent * 2 + "Value: '%s'" % os.environ[BIGDFT_CFG])
elif self.rcfile != '':
print(indent + 'Configuration options:')
print(indent * 2 + "Source: Configuration file '%s'" %
os.path.abspath(self.rcfile))
while not self.yes:
if not self.branch:
print(
indent + '#WARNING: You are compiling from a User Branch. Developments are discouraged in this case')
print(
indent + '# as compilation errors might lead to source deletion. For extensive developments the usage')
print(
indent + '# of a versioned branch is advised. Please ignore this warning if you are not a developer.')
ok = input('Do you want to continue (Y/n)? ')
if ok == 'n' or ok == 'N':
exit(0)
elif ok != 'y' and ok != 'Y' and repr(ok) != repr(''):
print('Please answer y or n')
else:
break
def selected(self, l):
return [val for val in l if val in self.modulelist]
def jhbuildaction(self, action, target, options=''):
"Call jhbuild to do action on target."
import os
command = " ".join((action, options, target))
ret = os.system(self.jhb + command)
if (ret != 0):
raise RuntimeError('JHBuild failed to complete :' + command)
def shellaction(self, path, modules, action, hidden=False):
"Perform a shell action, dump also the result if verbose is True."
import os
import sys
for mod in self.selected(modules):
directory = os.path.join(path, mod)
here = os.getcwd()
if os.path.isdir(directory):
#self.__dump('Treating directory '+directory)
sys.stdout.write('Module ' + mod +
' [' + directory + ']: ' + action)
sys.stdout.flush()
os.chdir(directory)
if hidden:
self.get_output(action)
else:
ierr = os.system(action)
if ierr != 0:
raise Exception('Error in action: "' +
action + '" for package: "' + mod + '"')
# print 'Error in action: "'+action+'" for package: "'+mod+'"'
# sys.exit(1)
os.chdir(here)
# self.__dump('done.')
sys.stdout.write(' (done)\n')
else:
sys.stdout.write('Cannot perform action "' + action +
'" on module "' + mod + '" directory not present in the build.\n')
sys.stdout.flush()
def get_output(self, cmd, verbose=True):
import subprocess
self.__dump('executing:', cmd, verbose=verbose)
# note the use of universal_newlines
# in python3, this forces the output to plain text instead of binary.
# this poorly named parameter was aliased as "text" in version 3.7
proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
(out, err) = proc.communicate()
self.__dump("program output:", out, verbose=verbose or len(out) > 0)
return out
def removefile(self, pattern, dirname, names):
"Delete the files matching the pattern"
import os
import fnmatch
for name in names:
if fnmatch.fnmatch(name, pattern):
self.__dump('removing', os.path.join(dirname, name))
os.remove(os.path.join(dirname, name))
def get_ac_argument(self, tgt, acmacro):
"Retrieve the list of ac arguments for the macro acmacro from file tgt"
import os
m4args = set()
if os.path.isfile(tgt):
for dd in get_macros(tgt, acmacro):
if len(dd) == 0:
continue
m4 = dd.split('[')[1]
m4args.add(m4.split(']')[0])
return list(m4args)
def get_m4_macros(self, tgt, previous_macros=[]):
"Identify the name of the proprietary m4 macros used in configure.ac"
import os
macros = set()
if os.path.isfile(tgt):
for regexp in self.m4_re:
for m4 in get_macros(tgt, regexp):
if len(m4) > 0 and not m4.strip().startswith('AC_DEFUN'):
m4t = m4.split('(')[0].strip()
if m4t not in previous_macros:
macros.add(m4t)
required = self.get_ac_argument(tgt, 'AC_REQUIRE')
for m in required:
found = m in previous_macros
if found:
continue
for regexp in self.m4_re:
found = regexp.lstrip('^') in m
if found:
break
if found:
macros.add(m)
return list(macros)
def get_m4_files(self, macros):
"Find the files needed for the definition of the proprietary macros"
import os
files = set()
# localize then the associated file in the m4 repository
tgt = os.path.join(self.srcdir, 'm4') + os.sep
# print 'XXXXX',macros
for m in macros:
ffs = get_files(tgt, m, 'AC_DEFUN')[0]
if ffs != '':
files.add(ffs)
# now for each of the files get all the macros which are required but not explicitly called
files = list(files)
newm4 = set()
for f in files:
tgt = os.path.join(self.srcdir, f)
newm = self.get_m4_macros(tgt, previous_macros=macros)
# print 'new macros',newm,f
for m4 in newm:
newm4.add(m4)
newm4 = list(newm4)
# print "new macros which have to be added",newm4,files
if len(newm4) > 0:
files = self.get_m4_files(macros + newm4)
return list(files)
def get_m4_dir(self, mod):
"Return the configure macro dir(s)"
import os
tgt = os.path.join(self.srcdir, mod, 'configure.ac')
return self.get_ac_argument(tgt, 'AC_CONFIG_MACRO_DIR')
def copyfiles(self, filelist, dest):
import os
import shutil
if not os.path.isdir(dest):
return
for f in filelist:
test = os.path.join(dest, os.path.basename(f))
if os.path.isfile(test):
if len(self.get_output('diff -q ' + f + ' ' + test, verbose=False)) == 0:
continue
try:
shutil.copy(f, dest)
except:
os.chmod(dest, 777) # ?? still can raise exception
shutil.copy(f, dest)
print('Copied file ' + f + ' in directory ' + dest)
def autogen(self):
"Perform the autogen action"
import os
# first copy the macros in the config.m4 directories of proprietary packages
for mod in self.selected(MAKEMODULES):
macros = self.get_m4_macros(
os.path.join(self.srcdir, mod, 'configure.ac'))
# print 'initial macros',mod,macros
files = self.get_m4_files(macros)
# print 'related files',files
# print 'directory to copy files',self.get_m4_dir(mod)
# now copy the files, overwriting the previously existing ones
for d in self.get_m4_dir(mod):
self.copyfiles(files, os.path.join(self.srcdir, mod, d))
self._setupone(mod)
#self.jhbuildaction(SETUP, self.package)
#self.shellaction(self.srcdir,self.modulelist,'autoreconf -fi')
def check(self):
"Perform the check action"
self.shellaction('.', CHECKMODULES, 'make check',
hidden=not self.verbose)
def make(self):
"Perform the simple make action"
self.shellaction('.', MANUALMAKEMODULES,
'make -j6 && make install', hidden=not self.verbose)
def dist(self):
"Perform make dist action"
import os
tarfile = os.path.join(self.builddir, self.package + '-suite.tar.gz')
disttime0 = self.filename_time(tarfile)
self.jhbuildaction(DIST, self.package + "-suite")
disttime1 = self.filename_time(tarfile)
if not (disttime1 == disttime0):
print('SUCCESS: distribution file "' + self.package +
'-suite.tar.gz" generated correctly')
else:
print(
'WARNING: the dist file seems not have been updated or generated correctly')
def build(self):
"Build the bigdft module with the options provided by the rcfile"
import os
# in the case of a nonbranch case, like a dist build, force checkout
# should the make would not work
co = '' if self.branch else ' -C'
if (self.verbose):
self.jhbuildaction(BUILD, self.package, options=co)
else:
self.jhbuildaction(TINDERBOX, self.package, options=co)
def _wipeout(self, mod):
import shutil
print('Wipe directory: ', mod)
shutil.rmtree(mod, ignore_errors=True)
def _cleanone(self, mod):
import os
self.jhbuildaction(UNINSTALL, mod)
self.jhbuildaction(CLEANONE, mod)
# here we should eliminate residual .mod files
os.walk(mod, self.removefile, "*.mod")
os.walk(mod, self.removefile, "*.MOD")
if not self.branch: # this is necessary as we come from a tarfile
self._wipeout(mod)
def cleanone(self):
self._cleanone(self.package)
def buildone(self):
self._buildone(self.package)
def clean(self):
"Clean files in the build directory"
# invert cleaning order for elegance
for mod in self.selected(MAKEMODULES[::-1]):
self._cleanone(mod)
def _buildone(self, mod):
print('Resetting: ', mod)
self._setupone(mod)
print('Building: ', mod)
self.jhbuildaction(BUILDONE, mod)
def _setupone(self, mod):
self.jhbuildaction(SETUP, mod, options=' -t ' + mod)
def startover(self):
"Wipe files in the makemodules directory"
if not self.branch:
print('ERROR: The action "startover" is allowed only from a developer branch')
exit(1)
import os
for mod in self.selected(MAKEMODULES):
self.get_output(self.jhb + UNINSTALL + mod)
self._wipeout(mod)
print('Building again...')
for mod in self.selected(MAKEMODULES):
self._buildone(mod)
self.build()
def dry_run(self):
"Do dry build"
self.get_output(self.jhb + DOT + self.package + DOTCMD)
def link(self):
"Show the linking line, when applicable"
import os
PPATH = "PKG_CONFIG_PATH"
addpath = os.path.join(self.builddir, 'install', 'lib', 'pkgconfig')
if PPATH in os.environ:
if addpath not in os.environ[PPATH].split(':'):
os.environ[PPATH] += ':' + addpath
else:
os.environ[PPATH] = addpath
includes = self.get_output('pkg-config --cflags ' + self.package)
libs = self.get_output('pkg-config --libs ' + self.package)
# add the external linalg at the end to avod linking problems
linalg = self.get_output(
'pkg-config --variable linalglibs ' + self.package)
plugin = self.get_output(
'pkg-config --variable plugin ' + self.package)
print('--------- Linking line to build with package "' + self.package + '":')
print(" " + includes + " " + libs)
def makefile_dump(self):
"Build the Makefile that the installation of BigDFT creates for performing the same actions on this build"
import os
sflist = []
sflist.append("""
#This Makefile is automatically generated from the BigDFT installer to avoid the calling to
#the installer again for future action on this build
#Clearly such actions only _assume_ that the build is fully functional and almost nothing
#can be done with this file if a problem might arise.
#Otherwise stated: this is an automatic message, please do not reply.
all: build
""")
# this should be done only if buildrc is there
for a in ACTIONS:
sflist.append(a + ': ')
sflist.append('\t' +
os.path.abspath(self.scriptpath) + ' ' + a + ' ' + self.package + ' -y')
mkfile = open(MKFILE, 'w')
for item in sflist:
mkfile.write("%s\n" % item)
# rcfile.write("\n")
mkfile.close()
def rcfile_from_env(self):
"Build the rcfile information from the chosen " + \
BIGDFT_CFG + " environment variable"
import os
if os.path.isfile(self.rcfile) and not os.path.isfile(RCFILE):
from shutil import copyfile
copyfile(self.rcfile, RCFILE)
print(
'The configuration file used has been copied in the build tree, file "' + RCFILE + '"')
return
if BIGDFT_CFG not in list(os.environ.keys()) or os.path.isfile(RCFILE):
return
print('The suite has been built from a single configure line.')
rclist = []
rclist.append(
"""#This is the configuration file for the BigDFT installer""")
rclist.append(
"""#This is a python script which is executed by the build suite """)
rclist.append(" ")
rclist.append(
"""#Add the condition testing to run tests and includes PyYaml""")
for cond in self.conditions:
rclist.append('conditions.add("' + cond + '")')
rclist.append("""#List the module the this rcfile will build""")
rclist.append("modules = ['" + self.package + "',]")
sep = ' """ '
confline = sep + os.environ[BIGDFT_CFG] + sep
rclist.append(
"#example of the potentialities of the python syntax in this file")
rclist.append("def env_configuration():")
rclist.append(" return " + confline)
rclist.append(
"#the following command sets the environment variable to give these settings")
rclist.append("#to all the modules")
rclist.append("import os")
rclist.append("os.environ['" + BIGDFT_CFG + "']=env_configuration()")
rclist.append(
"#here follow the configuration instructions for the modules built")
rclist.append(
"#we specify the configurations for the modules to customize the options if needed")
rclist.append("module_autogenargs.update({")
rclist.append(" ")
for mod in self.modulelist:
rclist.append("'" + mod + "': env_configuration(),")
rclist.append(" ")
rclist.append("})")
# then write the file
rcfile = open(RCFILE, 'w')
for item in rclist:
rcfile.write("%s\n" % item)
# rcfile.write("\n")
rcfile.close()
print("Your used configuration options have been saved in the file '%s'." % RCFILE)
print("Such file will be used for next builds, you might also save it in the 'rcfiles/'.")
print(
"Directory of the source for future use. The name might contain the hostname.")
def __del__(self):
import os
print(50 * '-')
print('Thank you for using the Installer of BigDFT suite.')
print('The action considered was:', self.action)
try:
if self.time0 is not None:
if not (self.time0 == self.target_time()) and self.target_time() != 0:
print(
'SUCCESS: The Installer seems to have built correctly', self.package, ' bundle')
print(
'All the available executables and scripts can be found in the directory')
print(
'"' + os.path.join(os.path.abspath(self.builddir), 'install', 'bin') + '"')
print(
'Before using the code consider sourcing the script:')
print(
' "' + os.path.join(os.path.abspath(self.builddir), 'install', 'bin', 'bigdftvars.sh') + '"')
if self.action in NEEDRC:
self.rcfile_from_env()
elif (self.action == 'build' or self.action == 'make'):
print('WARNING: The Installer seems NOT have created or updated',
self.package, ' binaries')
print(' (maybe everything was already compiled?)')
print('ACTION: check the compiling procedure.')
if self.branch:
print(
'HINT: It appears you are compiling from a branch source tree. Did you perform the action "autogen"?')
if not self.verbose and self.action == 'build':
print(
' HINT: Have a look at the file index.html of the buildlogs/ directory to find the reason')
if self.yes:
exit(1)
except:
print('Goodbye...')
if self.action not in NOMAKEFILE:
self.makefile_dump() # temporary
if __name__ == '__main__':
# import the uniparse module
import UniParse
# Redefine ArgumentParser to have the help message if no arguments
class Installer_Parser(UniParse.UniParser):
def error(self, message):
import sys
sys.stderr.write('error: %s\n' % message)
self.print_help()
self.exit()
parser = Installer_Parser(description='BigDFT suite Installer',
epilog='''
If you want more help type "%(prog)s help"
------------------------------------------------
For more information, visit www.bigdft.org''')
parser.option('action', nargs='?', default='help',
help='Action to be performed by the Installer.'
' (default: %(default)s)', choices=['help'] + [a for a in ACTIONS])
parser.option('package', nargs='?', default='bigdft',
help='Package to be built by the installer. (default: %(default)s)',
choices=CHECKMODULES)
parser.option('-f', '--file',
help='Use an alternative configuration file instead of the default configuration '
+ 'given by the environment variable %s' % BIGDFT_CFG)
parser.add_group(mutually_exclusive=True)
parser.group_option("-v", "--verbose", action="store_true",
help='Verbose output, default from a development branch')
parser.group_option("-q", "--quiet", action="store_true",
help='Verbosity disabled output, default from a development branch')
parser.option('-d', '--debug', action='store_true',
help='Verbose output, default from a development branch')
parser.option('-a', '--add-condition',
help='Add a condition for the compilation of the suite.')
parser.option('-y', '--yes', action='store_true',
help='Answer yes to dialog questions')
parser.option('-c', '--configure-line', remainder=True,
help='Specify the configure line to be passed (set BIGDFT_CONFIGURE_FLAGS variable)')
args = parser.args()
conds = None if args.add_condition is None else args.add_condition.split(
',')
if args.configure_line is not None:
cfg = ''
for i in args.configure_line:
if i is not None:
cfg += i + ' '
# scratch the BIGDFT_CFG environment variable
import os
os.environ[BIGDFT_CFG] = cfg
if args.action == 'help':
print("Quick overview of the BigDFT suite Installer program")
print(50 * '-')
print("USAGE: Installer.py <action> <package>")
print(50 * '-')
print('Available actions:')
actions = list(ACTIONS.keys())
actions.sort()
for a in actions:
print(a, ':')
print('\t', ACTIONS[a])
print(50 * '-')
print('Available packages:', CHECKMODULES)
print(50 * '-')
print(10 * "QIFI-" + ' (Quick Instructions For the Impatient)')
print('Ideally, there are two different policies:')
print('Developer: From a development branch, start by "autogen", then "build"')
print(' User: From a tarball, start by "build"')
print('Perform the "dry_run" command to have a graphical overview of the building procedure')
elif args.action == 'update':
yes = args.yes
for action in ['clean', 'autogen', 'build']:
BigDFTInstaller(action, args.package, args.file,
conds, args.verbose, args.quiet, yes)
yes = True
else:
BigDFTInstaller(args.action, args.package, args.file,
conds, args.verbose, args.quiet, args.yes)